package dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import util.bean.ResultSetProcessor;

import bean.Permission;
import bean.Role;
import bean.User;
import static util.DatabaseForMySQLUtil.*;

public class RoleDAO {
	private final static RoleDAO INSTANCE = new RoleDAO();

	private RoleDAO() {

	}

	public static RoleDAO getInstance() {
		return INSTANCE;
	}

	public void addRolePermission(Role role, Set<Permission> permssions) {
		String sql = "replace into roles_permissions_map(role_id,permission_id) values";
		for (Permission permssion : permssions) {
			sql += "(";
			sql += role.getId();
			sql += ",";
			sql += permssion.getId();
			sql += "),";
		}
		if (sql.endsWith(",")) {
			sql = sql.substring(0, sql.length() - 1);
			executeUpdate(sql);
		} else {
			return;
		}
	}

	public void addUserRoles(User user, Set<Role> roles) {
		String sql = "replace into users_roles_map(role_id,user_id) values";
		for (Role role : roles) {
			sql += "(";
			sql += role.getId();
			sql += ",";
			sql += user.getId();
			sql += "),";
		}
		if (sql.endsWith(",")) {
			sql = sql.substring(0, sql.length() - 1);
			executeUpdate(sql);
		} else {
			return;
		}
	}

	public int addRole(Role role) {
		String sql = "insert into roles(rolename,description) values('" + role.getName() + "','" + role.getDescription() + "')";
		int count = executeUpdate(sql);

		role.setId(getLastInsertId());
		return count;
	}

	@SuppressWarnings("unchecked")
	public Set<Role> getRoles(Long userId) {
		String sql = "select r.id,r.rolename,r.description from roles r,users_roles_map rm where rm.user_id = ? and r.id = rm.role_id";
		Set<Role> roles = (Set<Role>) query(sql, new ResultSetProcessor() {
			public Object exec(java.sql.ResultSet rs) throws SQLException {
				Set<Role> roles = new HashSet<Role>();

				while (rs.next()) {
					Role role = new Role();

					role.setId(rs.getLong("id"));
					role.setName(rs.getString("rolename"));
					role.setDescription(rs.getString("description"));
					role.setPermissions(getPermissions(role.getId()));

					roles.add(role);
				}
				return roles;
			}
		}, userId);

		return roles;
	}

	@SuppressWarnings("unchecked")
	public Set<String> getPermissions(Long roleId) {
		String sql = "select permission.permission from roles_permissions_map rmmap,roles_permissions permission where rmmap.role_id = ? and rmmap.permission_id = permission.id";

		Set<String> permissions = (Set<String>) query(sql, new ResultSetProcessor() {
			public Object exec(java.sql.ResultSet rs) throws SQLException {
				Set<String> permissions = new HashSet<String>();

				while (rs.next()) {
					permissions.add(rs.getString(1));
				}

				return permissions;
			}
		}, roleId);

		return permissions;
	}

	@SuppressWarnings("unchecked")
	public Set<Permission> getPermissions() {
		String sql = "select id,permission from roles_permissions";
		Set<Permission> permissions = (Set<Permission>) query(sql, new ResultSetProcessor() {
			public Object exec(ResultSet rs) throws SQLException {
				Set<Permission> permissions = new HashSet<Permission>();

				while (rs.next()) {
					permissions.add(new Permission(rs.getLong(1), rs.getString(2)));
				}

				return permissions;
			}
		});

		return permissions;
	}

	public int addPermission(String permission) {
		String sql = "insert into roles_permissions(permission) values('" + permission + "')";
		return executeUpdate(sql);
	}
}
